package com.yanqu.road.utils.property;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class Property {

	private Map<Integer, BigInteger> goods;
	@JsonIgnore
	private int weightsAdd; //累计权重

	public Property() {
		goods = new HashMap<>();
	}

	public Property(Property property) {
		goods = new HashMap<>();
		for (Entry<Integer, BigInteger> entry : property.getGoods().entrySet()) {
			goods.put(entry.getKey(), entry.getValue());
		}
	}

	//判断是不是空的
	public boolean isNothing(){
		boolean result = true;
		for (BigInteger num : goods.values()){
			if(num.compareTo(BigInteger.ZERO) != 0){
				result = false;
			}
		}
		return result;
	}

	public void addProperty(Property property) {
		if (property != null) {
			for (Entry<Integer, BigInteger> entry : property.getGoods().entrySet()) {
				if (goods.containsKey(entry.getKey())) {
					goods.put(entry.getKey(), goods.get(entry.getKey()).add(entry.getValue()));
				} else {
					goods.put(entry.getKey(), entry.getValue());
				}
			}
		}
	}

	//物品翻倍
	public void rideProperty(int multiple) {
		rideProperty(BigInteger.valueOf(multiple));
	}

	public void rideProperty(BigDecimal multiple) {
		for (Integer goodId : goods.keySet()) {
			goods.put(goodId, new BigDecimal(goods.get(goodId)).multiply(multiple).setScale(0, BigDecimal.ROUND_UP).toBigInteger());
		}
	}

	public void rideProperty(long multiple) {
		rideProperty(BigInteger.valueOf(multiple));
	}

	public void rideProperty(BigInteger multiple) {
		for (Integer goodId : goods.keySet()) {
			goods.put(goodId, goods.get(goodId).multiply(multiple));
		}
	}

	public Property(int goodsId, BigInteger count) {
		goods = new HashMap<>();
		goods.put(goodsId, count);
	}

	public Property(int goodsId, long count) {
		goods = new HashMap<>();
		goods.put(goodsId, BigInteger.valueOf(count));
	}

	public void addProperty(int goodsId, BigInteger count) {
		if (goods.containsKey(goodsId)) {
			count = count.add(goods.get(goodsId));
		}
		goods.put(goodsId, count);
	}

	public void addProperty(int goodsId, int count) {
		addProperty(goodsId, BigInteger.valueOf(count));
	}

	public void addProperty(int goodsId, long count) {
		addProperty(goodsId, BigInteger.valueOf(count));
	}

	public boolean removeProperty(int goodsId, BigInteger count) {
		BigInteger goodsCount = goods.get(goodsId);

		if (goodsCount != null && goodsCount.compareTo(count) > 0) {
			goods.put(goodsId, goodsCount.subtract(count));
			return true;
		}
		if (goodsCount != null && goodsCount.equals(count)) {
			goods.remove(goodsId);
			return true;
		}
		return false;
	}

	//出bug扣的，有得扣扣掉，没得扣扣到0为止
	public boolean removePropertyBug(int goodsId, BigInteger count) {
		BigInteger goodsCount = goods.get(goodsId);

		if (goodsCount != null && goodsCount.compareTo(count) > 0) {
			goods.put(goodsId, goodsCount.subtract(count));
			return true;
		}
		if (goodsCount != null && goodsCount.compareTo(count) <= 0) {
			goods.remove(goodsId);
			return true;
		}
		return false;
	}

	public BigInteger removeProperty(int goodsId) {
		return goods.remove(goodsId);
	}

	public boolean isEnoughRemove(Property property) {
		boolean result = true;
		for (Entry<Integer, BigInteger> entry : property.getGoods().entrySet()) {
			Integer goodsId = entry.getKey();
			BigInteger goodNum = entry.getValue();
			BigInteger goodsCountHave = goods.get(goodsId);
			if (goodsCountHave == null || goodsCountHave.compareTo(goodNum) < 0) {
				result = false;
				break;
			}
		}
		return result;
	}

	/**
	 * 会修改内容
	 *
	 * @param property
	 * @return
	 */
	public boolean removeProperty(Property property) {
		if (!isEnoughRemove(property)) {
			return false;
		}
		for (Entry<Integer, BigInteger> entry : property.getGoods().entrySet()) {
			Integer goodsId = entry.getKey();
			BigInteger goodNum = entry.getValue();
			BigInteger goodsCountHave = goods.get(goodsId);
			if (goodsCountHave.compareTo(goodNum) == 0) {
				goods.remove(goodsId);
			} else {
				goods.put(goodsId, goodsCountHave.subtract(goodNum));
			}
		}
		return true;
	}

	/**
	 * 是否有一样的奖励
	 *
	 * @return
	 */
	public boolean isHaveSameReward(Property property) {
		if (property.isNothing()) {
			return false;
		}
		for (Entry<Integer, BigInteger> entry : property.getGoods().entrySet()) {
			Integer goodsId = entry.getKey();
			BigInteger goodNum = entry.getValue();
			BigInteger goodsCountHave = goods.get(goodsId);
			if (goodsCountHave == null) {
				return false;
			}

			if (goodsCountHave.compareTo(goodNum) != 0) {
				return false;
			}
		}
		return true;
	}

	public Map<Integer, BigInteger> getGoods() {
		return goods;
	}

	public void setGoods(Map<Integer, BigInteger> goods) {
		this.goods = goods;
	}

	public void setGood(int goodsId, BigInteger num) {
		goods.put(goodsId, num);
	}

	public BigInteger getCountByGoodsId(int goodsId) {
		if (goods != null && goods.containsKey(goodsId)) {
			return goods.get(goodsId);
		}
		return BigInteger.ZERO;
	}

	//数量乘倍数
	public Property goodCountMultiNum(int num) {
		if (num < 0) {
			return this;
		}
		for (Entry<Integer, BigInteger> entry : goods.entrySet()) {
			entry.setValue(entry.getValue().multiply(BigInteger.valueOf(num)));
		}
		return this;
	}

	public void goodCountMultiNum(long num) {
		if (num <= 0) {
			return;
		}
		for (Entry<Integer, BigInteger> entry : goods.entrySet()) {
			entry.setValue(entry.getValue().multiply(BigInteger.valueOf(num)));
		}
	}

	//有小数的乘
	public void goodMulti(BigDecimal num) {
		goodMulti(num, BigDecimal.ROUND_UP);
	}

	public void goodMulti(BigDecimal num, int roundingMode) {
		if (num.compareTo(BigDecimal.ZERO) < 0) {
			return;
		}
		for (Entry<Integer, BigInteger> entry : goods.entrySet()) {
			BigInteger value = entry.getValue();
			value = num.multiply(new BigDecimal(value)).setScale(0,roundingMode).toBigInteger();
			entry.setValue(value);
		}
	}

	@JSONField(deserialize = false, serialize = false)
	public int getWeightsAdd() {
		return weightsAdd;
	}

	@JSONField(deserialize = false, serialize = false)
	public void setWeightsAdd(int weightsAdd) {
		this.weightsAdd = weightsAdd;
	}

	public String toHelperString() {
		String s = PropertyHelper.parsePropertyToString(this);
		return s;
	}
}
